#pragma semicolon 1
//強制1.7以後的新語法
#pragma newdecls required
#include <sourcemod>
#include <binhooks>

int maxcl;
int Survivor_Limit; 
int player_num = 0;

char line[128];

Handle Hostname;

int KillSpecial[MAXPLAYERS+1];
int HeadShotSpecial[MAXPLAYERS+1];

Handle timer_AllHUD = null;
Handle timerHOSTHUD = null;

bool l4d2_itempickup;
bool l4d2_emshud_info;

bool l4d2_shutdownTime = false;
bool l4d2_BinHook_LobbyUnreserve = false;

ConVar g_lobbyconnectonly;
ConVar Beijingtime, ghostnameenabled, ghostnametimer, ghostnametimes, killinfected, playerstatus, Totalnumber, LobbyUnreserve, connectonlysv, CountConsole, CountChat, CountTimer;

int Sghostnamecount, Killinterested, shutdownTime;
int SBeijingtime, Sghostnameenabled, Sghostnametimes, Skillinfected, Splayerstatus, STotalnumber, SLobbyUnreserve, Sconnectonlysv, SCountConsole, SCountChat;

float g_fMeleeNerf2;
float Sghostnametimer;

Handle shutdownTimer = null;

public Plugin myinfo =
{
	name = "EMS_HUD系统显示信息",
	author = "人生如梦",
	description = "EMS_HUD系统击杀显示信息",
	version = "1.0",
	url = "qq 79134786"
}

public void OnPluginStart()
{
	g_lobbyconnectonly = FindConVar("sv_allow_lobby_connect_only");
	
	//管理员指令.
	RegAdminCmd("sm_un", Command_Unreserve, ADMFLAG_BAN, "管理员手动移除匹配.");
	RegAdminCmd("sm_sn", Command_Shutdown, ADMFLAG_BAN ,"打开服务端崩溃菜单.");
	//控制台指令.
	RegServerCmd("sm_an1", Command_Shutdownnow_1, "倒计时崩溃服务端.");
	RegServerCmd("sm_an2", Command_Shutdownnow_2, "倒计时踢出所有玩家.");
	
	Beijingtime			= CreateConVar("l4d2_emshud_info_beijing_time", "1", "排行榜显示服务器北京时间. 0=禁用, 1=启用.", FCVAR_SPONLY);
	ghostnameenabled	= CreateConVar("l4d2_emshud_info_hostname_enabled", "1", "启用排行榜显示服务器名字? 0=禁用, 1=启用.", FCVAR_SPONLY);
	ghostnametimer		= CreateConVar("l4d2_emshud_info_hostname_timer", "30", "设置服务器名字的显示间隔(秒).", FCVAR_SPONLY);
	ghostnametimes		= CreateConVar("l4d2_emshud_info_hostname_times", "1", "设置服务器名字连续显示多少次.", FCVAR_SPONLY);
	killinfected		= CreateConVar("l4d2_emshud_info_killinfected", "8", "设置幸存者击杀特感排行榜的显示行数. 0=禁用(最大值8).", FCVAR_SPONLY);
	playerstatus		= CreateConVar("l4d2_emshud_info_player_status", "1", "排行榜显示玩家连接,闲置,旁观,特感,幸存者数量信息? 0=禁用, 1=启用.", FCVAR_SPONLY);
	Totalnumber			= CreateConVar("l4d2_emshud_info_total_number", "1", "排行榜显示当前总人数? 0=禁用, 1=启用.", FCVAR_SPONLY);
	
	LobbyUnreserve		= CreateConVar("l4d2_shutdown_binHook_lobbyunreserve", "1", "启用聊天窗指令!un关闭匹配? (注意:本地服务器无效) 0=禁用, 1=启用.", FCVAR_SPONLY);
	connectonlysv		= CreateConVar("l4d2_shutdown_binHook_lobbyunreserve_only", "1", "排行榜显示当前匹配状态? 0=禁用, 1=启用.", FCVAR_SPONLY);
	CountConsole		= CreateConVar("l4d2_shutdown_countdown_enabled_Console", "1", "启用控制台指令sm_an1崩溃服务端,指令sm_an2踢出所有玩家? 0=禁用, 1=启用.", FCVAR_SPONLY);
	CountChat			= CreateConVar("l4d2_shutdown_countdown_enabled_Chat", "1", "启用聊天窗指令!sn崩溃服务端或踢出所有玩家? 0=禁用, 1=启用.", FCVAR_SPONLY);
	CountTimer			= CreateConVar("l4d2_shutdown_countdown_timer", "5", "设置倒计时的时间/秒.", FCVAR_SPONLY);
	
	Beijingtime.AddChangeHook(SConVarChanged);
	ghostnameenabled.AddChangeHook(SConVarChanged);
	ghostnametimer.AddChangeHook(SConVarChanged);
	ghostnametimes.AddChangeHook(SConVarChanged);
	killinfected.AddChangeHook(SConVarChanged);
	playerstatus.AddChangeHook(SConVarChanged);
	Totalnumber.AddChangeHook(SConVarChanged);
	
	LobbyUnreserve.AddChangeHook(SConVarChanged);
	connectonlysv.AddChangeHook(SConVarChanged);
	CountConsole.AddChangeHook(SConVarChanged);
	CountChat.AddChangeHook(SConVarChanged);
	
	HookEvent("player_death", Event_playerdeathinfo);//玩家死亡.
	HookEvent("round_start", Event_RoundStartinfo);//回合开始.
	HookEvent("round_end", Event_RoundEndinfo);//回合结束.
	
	AutoExecConfig(true, "l4d2_emshud_info");
}

public void SConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
{
	l4d2emshudinfo();
}

void l4d2emshudinfo()
{
	SBeijingtime = Beijingtime.IntValue;
	Sghostnameenabled = ghostnameenabled.IntValue;
	Sghostnametimer = ghostnametimer.FloatValue;
	Sghostnametimes = ghostnametimes.IntValue;
	Skillinfected = killinfected.IntValue;
	Splayerstatus = playerstatus.IntValue;
	STotalnumber = Totalnumber.IntValue;
	SLobbyUnreserve = LobbyUnreserve.IntValue;
	Sconnectonlysv = connectonlysv.IntValue;
	SCountConsole = CountConsole.IntValue;
	SCountChat = CountChat.IntValue;
}

//地图开始
public void OnMapStart()
{	
	l4d2emshudinfo();
	
	player_num = 0;
	
	l4d2_itempickup = false;
	l4d2_emshud_info = false;
}

//地图结束.
public void OnMapEnd()
{
	delete timer_AllHUD;
	delete timerHOSTHUD;
}

//玩家连接
public void OnClientConnected(int client)
{   
	if(!IsFakeClient(client))
	{
		player_num+=1;
		KillSpecial[client] = 0;
		HeadShotSpecial[client] = 0;
	}
}

//玩家离开.
public void OnClientDisconnect(int client)
{   
	if(!IsFakeClient(client))
	{
		player_num-=1;
		KillSpecial[client] = 0;
		HeadShotSpecial[client] = 0;
	}
}

int SurvivorLimit()
{
	Handle invalid = INVALID_HANDLE;
	Handle downtownrun = FindConVar("l4d_maxplayers");
	Handle toolzrun = FindConVar("sv_maxplayers");
	if (downtownrun != (invalid))
	{
		int downtown = (GetConVarInt(FindConVar("l4d_maxplayers")));
		
		if (downtown >= 1)
		{
			maxcl = (GetConVarInt(FindConVar("l4d_maxplayers")));
		}
	}
	if (toolzrun != (invalid))
	{
		int toolz = (GetConVarInt(FindConVar("sv_maxplayers")));
		if (toolz >= 1)
		{
			maxcl = (GetConVarInt(FindConVar("sv_maxplayers")));
		}
	}
	if (downtownrun == (invalid) && toolzrun == (invalid))
	{
		maxcl = (MaxClients);
	}
	return maxcl;
}

//回合结束.
public void Event_RoundEndinfo(Event event, const char[] name, bool dontBroadcast)
{
	OnMapEnd();
	
	delay_RemoveAllHUD();
	delay_RemoveHOSTHUD();
	
	if(!l4d2_emshud_info)
	{
		//设置布尔值.
		l4d2_emshud_info = true;
	}
}

//回合开始.
public void Event_RoundStartinfo(Event event, const char[] name, bool dontBroadcast)
{
	Killinterested = 0;
	Sghostnamecount = 1;
	g_fMeleeNerf2 = 0.99;
	
	if(l4d2_emshud_info)
	{
		for (int i = 1; i <= MaxClients; i++)
		{ 
			if (IsClientConnected(i) && IsClientInGame(i) && !IsFakeClient(i))
			{
				KillSpecial[i] = 0;
				HeadShotSpecial[i] = 0;
			}
		}
		
		delete timer_AllHUD;
		timer_AllHUD = CreateTimer(1.0, displayinfo, _, TIMER_REPEAT);
		
		if(Sghostnameenabled)
		{
			l4d2timerHOSTHUD();
		}
		
		l4d2_emshud_info = false;
	}
}

//玩家连接成功.
public void OnClientPostAdminCheck(int client)
{
	if (IsFakeClient(client))
		return;
		
	if(!l4d2_itempickup)
	{
		delete timer_AllHUD;
		timer_AllHUD = CreateTimer(1.0, displayinfo, _, TIMER_REPEAT);
		
		if(Sghostnameenabled)
		{
			l4d2timerHOSTHUD();
		}
		l4d2_itempickup = true;
	}
}

void l4d2timerHOSTHUD()
{
	delete timerHOSTHUD;
	timerHOSTHUD = CreateTimer(0.1, displayHOST, _, TIMER_REPEAT);
}

public Action displayinfo(Handle timer)
{
	//清除所有HUD.
	delay_RemoveAllHUD();
	
	//显示击杀特感排行榜.
	if(Skillinfected > 0)
		displaykillinfected();
	
	//显示匹配状态.
	if(Sconnectonlysv == 1)
		displaykillinfected2();
	
	//显示服务器北京时间.
	if(SBeijingtime == 1)
		displaykillinfected3();
	
	//显示玩家连接,闲置,旁观,幸存者数量信息.
	if(Splayerstatus == 1)
		displaykillinfected4();
	
	//显示当前人数.
	if(STotalnumber == 1)
		displaykillinfected5();
}

//清除所有HUD.
void delay_RemoveAllHUD()
{
	if(HUDSlotIsUsed(HUD_SCORE_TITLE))
		RemoveHUD(HUD_SCORE_TITLE);
	
	if(HUDSlotIsUsed(HUD_SCORE_4))
		RemoveHUD(HUD_SCORE_4);
		
	if(HUDSlotIsUsed(HUD_SCORE_3))
		RemoveHUD(HUD_SCORE_3);
	
	if(HUDSlotIsUsed(HUD_SCORE_1))
		RemoveHUD(HUD_SCORE_1);
	
	//清理击杀特感排行榜.
	if(HUDSlotIsUsed(HUD_SCORE_2))
		RemoveHUD(HUD_SCORE_2);
	
	if(HUDSlotIsUsed(HUD_LEFT_BOT))
		RemoveHUD(HUD_LEFT_BOT);
	
	if(HUDSlotIsUsed(HUD_MID_BOT))
		RemoveHUD(HUD_MID_BOT);
	
	if(HUDSlotIsUsed(HUD_RIGHT_TOP))
		RemoveHUD(HUD_RIGHT_TOP);
	
	if(HUDSlotIsUsed(HUD_RIGHT_BOT))
		RemoveHUD(HUD_RIGHT_BOT);
	
	if(HUDSlotIsUsed(HUD_TICKER))
		RemoveHUD(HUD_TICKER);
	
	if(HUDSlotIsUsed(HUD_FAR_LEFT))
		RemoveHUD(HUD_FAR_LEFT);
	
	if(HUDSlotIsUsed(HUD_FAR_RIGHT))
		RemoveHUD(HUD_FAR_RIGHT);
	
	if(HUDSlotIsUsed(HUD_MID_BOX))
		RemoveHUD(HUD_MID_BOX);
}

public Action displayHOST(Handle timer)
{
	//清除服务器中文名HUD.
	delay_RemoveHOSTHUD();
	//显示服务器中文名HUD.
	if(!Sghostnameenabled)
	{
		timerHOSTHUD = null;
		return Plugin_Stop;
	}
	if(Sghostnamecount <= Sghostnametimes)
	{
		displaykillinfected6();
		
		if(g_fMeleeNerf2 <= 0.01)
		{
			Sghostnamecount += 1;
		}
	}
	else
	{
		CreateTimer(Sghostnametimer, SGHOSTNAMEHUD, _, TIMER_FLAG_NO_MAPCHANGE);
		timerHOSTHUD = null;
		return Plugin_Stop;
	}
	return Plugin_Continue;
}

public Action SGHOSTNAMEHUD(Handle timer)
{
	Sghostnamecount = 1;
	l4d2timerHOSTHUD();
}

//清除服务器中文名HUD.
void delay_RemoveHOSTHUD()
{
	if(HUDSlotIsUsed(HUD_LEFT_TOP))
		RemoveHUD(HUD_LEFT_TOP);
}

void displaykillinfected6()
{
	if(g_fMeleeNerf2 <= 0.01)
		g_fMeleeNerf2 = 0.99;
	else
		g_fMeleeNerf2 -= 0.01;
	
	char HosName[256];
	Hostname = FindConVar("hostname");
	GetConVarString(Hostname, HosName, sizeof(HosName));
	Format(line, sizeof(line), "%s", HosName);
	
	HUDSetLayout(HUD_LEFT_TOP,HUD_FLAG_ALIGN_LEFT|HUD_FLAG_NOBG|HUD_FLAG_BLINK|HUD_FLAG_COUNTDOWN_WARN,line);
	HUDPlace(HUD_LEFT_TOP,g_fMeleeNerf2,0.06,1.0,0.03);
}

public void Event_playerdeathinfo(Event event, const char[] name, bool dontBroadcast)
{
	int client = GetClientOfUserId(event.GetInt("userid"));
	int attacker = GetClientOfUserId(event.GetInt("attacker"));
	int headshot = GetEventInt(event, "headshot");
	
	if(IsValidClient(client) && GetClientTeam(client) == 3)
	{
		Killinterested += 1;
		
		if(IsValidClient(attacker) && GetClientTeam(attacker) == 2)
		{
			KillSpecial[attacker] += 1;
			
			if(headshot)
			{
				HeadShotSpecial[attacker]+=1;
			}
		}
	}
}

void displaykillinfected()
{
	int client;
	int players;
	
	int players_clients[MAXPLAYERS+1];
	for (client = 1; client <= MaxClients; client++)
	{
		if (IsClientInGame(client) && !IsFakeClient(client) && GetClientTeam(client) == 2) 
			players_clients[players++] = client;
	}
	SortCustom1D(players_clients, 10, SortByDamageDesc);
	
	if (GetAllPlayerCountAll1() > 0)
	{
		int ValueSize = GetValueSize();
	
		if(ValueSize)
			Format(line, sizeof(line), "特感/爆头  总计死亡: %d", Killinterested);
		else
			Format(line, sizeof(line), "总计死亡特感: %d", Killinterested);
	}
	else
		Format(line, sizeof(line), "总计死亡特感: %d", Killinterested);
		
	HUDSetLayout(HUD_SCORE_2,HUD_FLAG_ALIGN_LEFT|HUD_FLAG_NOBG,line);
	HUDPlace(HUD_SCORE_2,0.00,0.12,1.0,0.03);
	
	//默认显示8行.
	for (int i; i <= Skillinfected; i++)
	{
		client = players_clients[i];
		
		if (IsValidClient(client) && !IsFakeClient(client) && GetClientTeam(client) == 2 && KillSpecial[client] > 0)
		{
			Format(line, sizeof(line), "%i:%2d/%d ← %N", i+1, KillSpecial[client], HeadShotSpecial[client], client);
			
			if(i == 0)
			{
				HUDSetLayout(HUD_LEFT_BOT,HUD_FLAG_ALIGN_LEFT|HUD_FLAG_NOBG|HUD_FLAG_BLINK|HUD_FLAG_COUNTDOWN_WARN,line);
				HUDPlace(HUD_LEFT_BOT,0.00,0.15,1.0,0.03);
			}
			if(i == 1)
			{
				HUDSetLayout(HUD_MID_BOT, HUD_FLAG_ALIGN_LEFT|HUD_FLAG_NOBG,line);
				HUDPlace(HUD_MID_BOT,0.00,0.03 * i +0.15,1.0,0.03);
			}
			if(i == 2)
			{
				HUDSetLayout(HUD_RIGHT_TOP,HUD_FLAG_ALIGN_LEFT|HUD_FLAG_NOBG,line);
				HUDPlace(HUD_RIGHT_TOP,0.00,0.03 * i +0.15,1.0,0.03);
			}
			if(i == 3)
			{
				HUDSetLayout(HUD_RIGHT_BOT,HUD_FLAG_ALIGN_LEFT|HUD_FLAG_NOBG,line);
				HUDPlace(HUD_RIGHT_BOT,0.00,0.03 * i +0.15,1.0,0.03);
			}
			if(i == 4)
			{
				HUDSetLayout(HUD_TICKER,HUD_FLAG_ALIGN_LEFT|HUD_FLAG_NOBG,line);
				HUDPlace(HUD_TICKER,0.00,0.03 * i +0.15,1.0,0.03);
			}
			if(i == 5)
			{
				HUDSetLayout(HUD_FAR_LEFT,HUD_FLAG_ALIGN_LEFT|HUD_FLAG_NOBG,line);
				HUDPlace(HUD_FAR_LEFT,0.00,0.03 * i +0.15,1.0,0.03);
			}
			if(i == 6)
			{
				HUDSetLayout(HUD_FAR_RIGHT,HUD_FLAG_ALIGN_LEFT|HUD_FLAG_NOBG,line);
				HUDPlace(HUD_FAR_RIGHT,0.00,0.03 * i +0.15,1.0,0.03);
			}
			if(i == 7)
			{
				HUDSetLayout(HUD_MID_BOX,HUD_FLAG_ALIGN_LEFT|HUD_FLAG_NOBG,line);
				HUDPlace(HUD_MID_BOX,0.00,0.03 * i +0.15,1.0,0.03);
			}
		}
	}
}

bool GetValueSize()
{
	for(int i = 1; i <= MaxClients; i++)
		if (IsValidClient(i) && !IsFakeClient(i) && GetClientTeam(i) == 2)
			if(KillSpecial[i] > 0)
				return true;
	return false;
}

void displaykillinfected2()
{
	if(g_lobbyconnectonly.BoolValue)
		Format(line, sizeof(line), "匹配状态:(开启)");
	else
		Format(line, sizeof(line), "匹配状态:(关闭)");
		
	HUDSetLayout(HUD_SCORE_3,HUD_FLAG_ALIGN_LEFT|HUD_FLAG_NOBG,line);
	HUDPlace(HUD_SCORE_3,0.43,0.00,1.0,0.03);
}

void displaykillinfected3()
{
	char szTime[16], year[16], month[16], date[16];
	FormatTime(szTime, sizeof(szTime), "%H:%M:%S"); 
	FormatTime(year, sizeof(year), "%Y");
	FormatTime(month, sizeof(month), "%m");
	FormatTime(date, sizeof(date), "%d");
	
	Format(line, sizeof(line), "%s‐%s‐%s   %s", year, month, date, szTime);
	HUDSetLayout(HUD_SCORE_TITLE,HUD_FLAG_ALIGN_LEFT|HUD_FLAG_NOBG,line);
	HUDPlace(HUD_SCORE_TITLE,0.70,0.00,1.0,0.03);
}

void displaykillinfected4()
{
	Format(line, sizeof(line), "连接: %d 闲置: %d 旁观: %d 特感: %d 幸存者: %d", GetAllPlayerCountAll2(), GetAllPlayerCountAll3(), GetAllPlayerCountAll4(), GetAllPlayerCountAll5(3), GetAllPlayerCountAll5(2));
	HUDSetLayout(HUD_SCORE_4,HUD_FLAG_ALIGN_LEFT|HUD_FLAG_NOBG,line);
	HUDPlace(HUD_SCORE_4,0.00,0.00,1.0,0.03);
}


void displaykillinfected5()
{
	//显示当前人数和总位置.
	Survivor_Limit = SurvivorLimit();
	Format(line, sizeof(line), "当前人数:(%d / %d)", player_num, Survivor_Limit);
	HUDSetLayout(HUD_SCORE_1,HUD_FLAG_ALIGN_LEFT|HUD_FLAG_NOBG,line);
	HUDPlace(HUD_SCORE_1,0.43,0.03,1.0,0.03);
}

int GetAllPlayerCountAll1()
{
	int count1 = 0;
	for (int i = 1; i <= MaxClients; i++)
	{
		if (IsClientInGame(i) && !IsFakeClient(i) && GetClientTeam(i) == 2)
		{
			count1++;
		}
	}
	return count1;
}

int GetAllPlayerCountAll2()
{
	int count2 = 0;
	for (int i = 1; i <= MaxClients; i++)
	{
		if (IsClientConnected(i) && !IsClientInGame(i) && !IsFakeClient(i))
		{
			count2++;
		}
	}
	return count2;
}

int GetAllPlayerCountAll3()
{
	int count3 = 0;
	for (int i = 1; i <= MaxClients; i++)
	{
		if (IsClientConnected(i) && IsClientInGame(i) && !IsFakeClient(i) && GetClientTeam(i) == 1 && IsClientIdle(i))
		{
			count3++;
		}
	}
	return count3;
}

int GetAllPlayerCountAll4()
{
	int count4 = 0;
	for (int i = 1; i <= MaxClients; i++)
	{
		if (IsClientConnected(i) && IsClientInGame(i) && !IsFakeClient(i) && GetClientTeam(i) == 1 && !IsClientIdle(i))
		{
			count4++;
		}
	}
	return count4;
}

int GetAllPlayerCountAll5(int team)
{
	int count5 = 0;
	for (int i = 1; i <= MaxClients; i++)
	{
		if (IsClientConnected(i) && IsClientInGame(i) && GetClientTeam(i) == team)
		{
			count5++;
		}
	}
	return count5;
}

bool IsClientIdle(int client)
{
	for(int i = 1; i <= MaxClients; i++)
	{
		if(!IsClientConnected(i))
			continue;
		if(!IsClientInGame(i))
			continue;
		if(!IsFakeClient(i))
			continue;
		if(!HasIdlePlayer(i))
			continue;

		int spectator_client = GetClientOfUserId(GetEntData(i, FindSendPropInfo("SurvivorBot", "m_humanSpectatorUserID")));

		if(spectator_client == client)
			return true;
	}
	return false;
}

bool HasIdlePlayer(int bot)
{
	int client = GetClientOfUserId(GetEntData(bot, FindSendPropInfo("SurvivorBot", "m_humanSpectatorUserID")));

	if(client)
	{
		if(IsClientInGame(client) && !IsFakeClient(client) && GetClientTeam(client) == 1)
		return true;
	} 
	return false;
}

public int SortByDamageDesc(int elem1, int elem2, const char[] array, Handle hndl)
{
	if (KillSpecial[elem1] > KillSpecial[elem2]) return -1;
	else if (KillSpecial[elem2] > KillSpecial[elem1]) return 1;
	else if (elem1 > elem2) return -1;
	else if (elem2 > elem1) return 1;
	return 0;
}

bool IsValidClient(int client)
{
	return (client > 0 && client <= MaxClients && IsClientInGame(client));
}

public Action Command_Unreserve(int client, int args) 
{
	if(SLobbyUnreserve == 0)
	{
		PrintToChat(client,"\x04[提示]\x05聊天窗指令\x03!un\x05关闭匹配没有启用.");
		return Plugin_Handled;
	}
	if(SLobbyUnreserve == 1)
	{
		if(l4d2_BinHook_LobbyUnreserve == false)
		{
			BinHook_LobbyUnreserve();
			PrintToChatAll("\x04[提示]\x03%N\x05关闭了大厅匹配!", client);
			l4d2_BinHook_LobbyUnreserve = true;
		}
		else
			PrintToChatAll("\x04[提示]\x05匹配已移除,无需重复移除.");
	}
	return Plugin_Handled;
}

public Action Command_Shutdown(int client, int args) 
{
	if(SCountChat == 0)
	{
		PrintToChat(client,"\x04[提示]\x05指令!sn没有启用.");
		return Plugin_Handled;
	}
	if(SCountChat == 1)
	{
		Handle menu = CreateMenu(Shutdown_Menu);

		SetMenuTitle(menu, "请选择执行方式:");
		AddMenuItem(menu, "option1", "崩溃服务端");
		AddMenuItem(menu, "option2", "踢出所有玩家");
		AddMenuItem(menu, "option3", "关闭倒计时");
		
		SetMenuExitButton(menu, true);
		DisplayMenu(menu, client, MENU_TIME_FOREVER);
	}
	return Plugin_Handled;
}

public int Shutdown_Menu(Handle menu, MenuAction action, int client, int itemNum)
{
	if ( action == MenuAction_Select ) 
	{
		switch (itemNum)
		{
			case 0:
			{
				if(shutdownTimer == null)
				{
					shutdownTimer = CreateTimer(1.0, Timer_Countdown_1, _, TIMER_REPEAT);
					shutdownTime = GetConVarInt(CountTimer);
					l4d2_shutdownTime = true;
				}
				else
				{
					PrintToChat(client, "\x04[提示]\x05已存在服务端崩溃倒计时,无需重复执行.");
				}
			}
			case 1:
			{
				if(shutdownTimer == null)
				{
					shutdownTimer = CreateTimer(1.0, Timer_Countdown_2, _, TIMER_REPEAT);
					shutdownTime = GetConVarInt(CountTimer);
					l4d2_shutdownTime = true;
				}
				else
				{
					PrintToChat(client, "\x04[提示]\x05已存在服务端崩溃倒计时,无需重复执行.");
				}
			}
			case 2:
			{
				if(shutdownTimer != null)
				{
					PrintHintText(client, "[系统] 已停止倒计时...");
					l4d2_shutdownTime = false;
					delete shutdownTimer;
				}
				else
				{
					PrintToChat(client, "\x04[提示]\x05当前没有启动倒计时.");
				}
			}
		}
	}
}

public Action Command_Shutdownnow_1(int args)
{
	if(SCountConsole == 0)
	{
		PrintToServer("[提示]控制台指令sm_an没有启用.");
		return Plugin_Handled;
	}
	if(SCountConsole == 1)
	{
		if(shutdownTimer == null)
		{
			shutdownTimer = CreateTimer(1.0, Timer_Countdown_1, _, TIMER_REPEAT);
			shutdownTime = GetConVarInt(CountTimer);
			l4d2_shutdownTime = true;
		}
		else
		{
			PrintToServer("[系统] 已取消服务端崩溃...");
			l4d2_shutdownTime = false;
			delete shutdownTimer;
		}
	}
	return Plugin_Handled;
}

public Action Timer_Countdown_1(Handle timer)
{
	if(l4d2_shutdownTime == false)
	{
		PrintToChatAll("[系统] 已取消服务端崩溃...");
		shutdownTimer = null;
		return Plugin_Stop;
	}
	if(shutdownTime <= GetConVarInt(CountTimer))
	{
		PrintHintTextToAll("[系统] 服务器将于 %i 秒后被爆破!!!", shutdownTime);
	}
	if(shutdownTime <= 0)
	{
		PrintHintTextToAll("[系统] 服务器已被爆破!!!");
	}
	if(shutdownTime <= -1)
	{
		shutdownTimer = null;
		auto_restart_server();
		return Plugin_Stop;
	}
	shutdownTime -= 1;
	return Plugin_Continue;
}

void auto_restart_server()
{
	SetCommandFlags("crash", GetCommandFlags("crash") &~ FCVAR_CHEAT);
	ServerCommand("crash");
	SetCommandFlags("sv_crash", GetCommandFlags("sv_crash") &~ FCVAR_CHEAT);
	ServerCommand("sv_crash");
}

public Action Command_Shutdownnow_2(int args)
{
	if(SCountConsole == 0)
	{
		PrintToServer("[提示]控制台指令sm_an没有启用.");
		return Plugin_Handled;
	}
	if(SCountConsole == 1)
	{
		if(shutdownTimer == null)
		{
			shutdownTimer = CreateTimer(1.0, Timer_Countdown_2, _, TIMER_REPEAT);
			shutdownTime = GetConVarInt(CountTimer);
			l4d2_shutdownTime = true;
		}
		else
		{
			PrintToServer("[系统] 已取消倒计时...");
			l4d2_shutdownTime = false;
			delete shutdownTimer;
		}
	}
	return Plugin_Handled;
}

//public Action Timer_Countdown_2(Handle timer, int client)
public Action Timer_Countdown_2(Handle timer)
{
	if(l4d2_shutdownTime == false)
	{
		PrintToChatAll("[系统] 已取消踢出所有玩家...");
		shutdownTimer = null;
		return Plugin_Stop;
	}
	if(shutdownTime <= GetConVarInt(CountTimer))
	{
		PrintHintTextToAll("[系统] 服务器将于 %i 秒后踢出所有玩家!!!", shutdownTime);
	}
	if(shutdownTime <= 0)
	{
		PrintHintTextToAll("[系统] 已踢出所有玩家!!!");
	}
	if(shutdownTime <= -1)
	{
		shutdownTimer = null;
		l4d2_KickClient();
		return Plugin_Stop;
	}
	shutdownTime -= 1;
	return Plugin_Continue;
}

void l4d2_KickClient()
{
	for (int i = 1; i <= MaxClients; i++)
	{
		if (IsClientConnected(i) && !IsFakeClient(i))
		{
			KickClient(i, "该会话已不可用");
		}
	}
}